import Button from "../../Button";
import Drawer from "../../Drawer";
import React, { useEffect, useRef, useState } from "react";
import Tree from "../Tree";
import {
  isNew,
  isRoot,
  createNewTempNode,
  replaceTempNodeKey,
} from "../Tree/utils";
import type { TreeRef } from "../Tree/type";
import type { EditableTreeProps } from "./type";
import { cloneTreeData, findNode, findParentNode } from "./utils";

export default EditableTree;

function EditableTree({
  title,
  drawerTitle,
  addChildText,
  total,
  treeData: propsTreeData,
  visiable,
  maxShowDeepth,
  maxCreateDeepth,
  nodeTitleChangeValidator,
  onChange,
  onNodeTitleChange,
  onNodeRemove,
  onNodeAdd,
  onVisiable,
}: EditableTreeProps) {
  const [treeData, setTreeData] = useState([...propsTreeData]);

  const addMockHandler = (parentKey: string | number) => {
    const newNode = createNewTempNode();
    if (isRoot(parentKey)) {
      treeData.push(newNode);
    } else {
      const node = findNode(parentKey, treeData);
      if (!node) throw Error(`查找节点失败，找不到 key：${parentKey}`);
      if (!node.children) node.children = [];
      node.children.push(newNode);
    }
    setTreeData(cloneTreeData(treeData) || []); // TODO, 原来使用 deepClone ，不用的话，子节点不触发刷新
  };

  const addHandler = (key: string | number, title: string) => {
    // 创建了节点以后，要把节点的 key 前缀特征去掉
    const node = findNode(key, treeData);
    const parentKey = findParentNode(key, treeData);
    if (!node) throw Error(`查找节点失败，找不到 key: ${key}`);
    node.key = replaceTempNodeKey(node.key);
    node.title = title;
    let nextTreeData = cloneTreeData(treeData) || [];
    setTreeData(nextTreeData);
    // 注意，这里使用的是父级的 key，当前节点的 key 是临时的值
    onNodeAdd?.(parentKey, title, nextTreeData);
    onChange?.(nextTreeData);
  };

  const removeHandler = (key: string | number) => {
    const newTreeData = cloneTreeData(treeData, key) || [];
    // 把自己内部的临时数据及时改掉，当通过接口拉到新数据的时候可以无感更新
    setTreeData(newTreeData);
    // 告诉外面，要删除的 key，如果是新增的未保存节点，那么静默删除，不用通知外层
    if (isNew(key)) return;
    onNodeRemove?.(key, newTreeData);
    onChange?.(newTreeData);
  };

  useEffect(() => setTreeData(propsTreeData), [propsTreeData]);

  const childrenRef = useRef<TreeRef>(null);

  const handleClose = () => {
    childrenRef.current?.setOnEditingKey(null);
    onVisiable?.(false);
  };

  return (
    <>
      <Drawer
        open={visiable}
        width="550"
        title={drawerTitle ?? "管理目录"}
        onClose={handleClose}
        showConfirm={false}
        footer={
          <div style={{ textAlign: "right" }}>
            <Button onClick={handleClose}>关闭</Button>
          </div>
        }
      >
        <Tree
          editable
          fullHeight
          hiddenCount
          total={total}
          title={title}
          addChildText={addChildText}
          nodeTitleChangeValidator={nodeTitleChangeValidator}
          onChange={setTreeData}
          onNodeRemove={removeHandler}
          onMockChildAdd={addMockHandler}
          onNodeAdd={addHandler}
          onNodeTitleChange={onNodeTitleChange}
          treeData={treeData}
          maxShowDeepth={maxShowDeepth}
          maxCreateDeepth={maxCreateDeepth}
          ref={childrenRef}
        />
      </Drawer>
    </>
  );
}
